package cn.ingrun.utils.redisCache.server;


import cn.ingrun.utils.redisUtil.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * Author ingrun
 * Date 2020/9/28 15:50
 */
@Service
public class RedisCacheServerImpl implements RedisCacheServer {


    private RedisUtil redisUtil;

    @Autowired
    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Override
    public String getRedisCacheKey(String methodName, String[] parameterNames, Object[] parameterValue) {
        StringBuilder redisKey = new StringBuilder(methodName + ":" );
        for (int i = 0; i < parameterNames.length; i++) {
            redisKey.append(parameterNames[i]).append(":").append(parameterValue[i].toString());
        }
        return redisKey.toString();
    }

    @Override
    public boolean delCache(String methodName, String[] parameterNames, Object[] parameterValue) {
        String redisKey = getRedisCacheKey(methodName, parameterNames, parameterValue);
        return delCache(redisKey);
    }

    @Override
    public boolean delCache(String redisKey) {
        return redisUtil.del(redisKey);
    }

    @Override
    public void addCache(String methodName, String[] parameterNames, Object[] parameterValue, Object o, long time) {
        String redisKey = getRedisCacheKey(methodName, parameterNames, parameterValue);
        addCache(redisKey, o, time);
    }

    @Override
    public void addCache(String redisKey, Object o, long time) {
        if ( o.getClass() == String.class || isWrapClass(o.getClass()) ){
            redisUtil.set(redisKey, String.valueOf(o), time);
            return;
        }
        redisUtil.setObject(redisKey, o, time);
    }

    @Override
    public String getCache(String methodName, String[] parameterNames, Object[] parameterValue) {
        String redisKey = getRedisCacheKey(methodName, parameterNames, parameterValue);
        return redisUtil.get(redisKey);
    }

    @Override
    public String getCache(String redisKey) {
        return null;
    }

    @Override
    public <T> T getCache(String methodName, String[] parameterNames, Object[] parameterValue, Class<T> t) {
        String redisKey = getRedisCacheKey(methodName, parameterNames, parameterValue);
        return redisUtil.getObject(redisKey, t);
    }

    @Override
    public Object getCache(String redisKey, Class<?> methodReturnType) {
        if ( methodReturnType == String.class || methodReturnType == Character.class || methodReturnType == char.class ){
            return redisUtil.get(redisKey);
        }
        if ( methodReturnType == int.class || methodReturnType == Integer.class ){
            return Integer.parseInt(redisUtil.get(redisKey));
        }
        if ( methodReturnType == Boolean.class || methodReturnType == boolean.class ){
            return Boolean.parseBoolean(redisUtil.get(redisKey));
        }
        if ( methodReturnType == Byte.class || methodReturnType == byte.class ){
            return Byte.parseByte(redisUtil.get(redisKey));
        }
        if ( methodReturnType == Short.class || methodReturnType == short.class ){
            return Short.parseShort(redisUtil.get(redisKey));
        }
        if ( methodReturnType == Long.class || methodReturnType == long.class ){
            return Long.parseLong(redisUtil.get(redisKey));
        }
        if ( methodReturnType == Float.class || methodReturnType == float.class ){
            return Float.parseFloat(redisUtil.get(redisKey));
        }
        if ( methodReturnType == Double.class || methodReturnType == double.class ){
            return Double.parseDouble(redisUtil.get(redisKey));
        }
        return redisUtil.getObject(redisKey, methodReturnType);
    }

    private static boolean isWrapClass(Class<?> clz) {
        try {
            return ((Class<?>)clz.getField("TYPE").get(null)).isPrimitive();
        } catch (Exception e) {
            return false;
        }


    }
}
